// const isObject = (target) => (typeof target === "object" || typeof target === "function") && target !== null; // 判断这个对象是不是对象或者是函数而不是null

// function deepClone (target, map = new WeakMap()) { // 传入一个对象,和一个weakMap
//   if (map.get(target)) { // 如果能得到这个target 就直接返回这个target就行了
//     return target;
//   }
//   // 获取当前值的构造函数：获取它的类型
//   let constructor = target.constructor; // 获取当前值的构造函数
//   // 检测当前对象target是否与正则、日期格式对象匹配
//   if (/^(RegExp|Date)$/i.test(constructor.name)) { // 如果对于构造函数的名字能用正则或者date匹配
//     // 创建一个新的特殊对象(正则类/日期类)的实例
//     return new constructor(target); // 就创建一个新的对象返回
//   }
//   if (isObject(target)) { // 如果是对象不是null
//     map.set(target, true);  // 为循环引用的对象做标记
//     if (typeof target === 'function') { // 如果是函数 直接返回
//       return target
//     }
//     const cloneTarget = Array.isArray(target) ? [] : {}; // 判断是数组还是对象
//     for (let prop in target) { // 遍历每个属性
//       if (target.hasOwnProperty(prop)) { // 如果是有这个属性
//         cloneTarget[prop] = deepClone(target[prop], map); // 拷贝返回
//       }
//     }
//     return cloneTarget; // 返回拷贝的目标值
//   } else {
//     return target; // 不是对象直接返回
//   }
// }

var isObject = (target) => (typeof target === 'function' || typeof target === 'object') && (target !== null)

function deepClone (target, map = new WeakMap()) {
  if (map.get(target)) {
    return target
  }
  let constructor = target.__proto__.constructor // 拿到这个的构造函数
  if (/^(RegExp|Date)$/.test(constructor.name)) {
    return new constructor(target)
  }
  if (isObject(target)) {
    map.set(target, true)
    if (typeof target === 'function') {
      return target
    }
    let cloneTarget = Array.isArray(target) ? [] : {}
    for (let key in target) {
      if (target.hasOwnProperty(key)) {
        cloneTarget[key] = deepClone(target[key], map)
      }
    }
    return cloneTarget
  } else {
    return target
  }
}

let obj1 = {
  name: '小李',
  age: 20,
  children: ['小王'],
  money: {
    'one': 10,
    'two': 20
  },
  birthday: new Date('2020-8-10'),
  regexp: new RegExp('nihao', 'g')
}
console.log(obj1);
let obj2 = deepClone(obj1)
obj2.name = '小张'
obj2.age = 23
obj2.children[0] = '小方'
obj2.money.one = 30
obj2.birthday = new Date('2022-8-9')
obj2.regexp = new RegExp('wobuhao', 'i')
console.log(obj1);
console.log(obj2);
// let isObject1 = (target) => (typeof target === 'function' || typeof target === 'object') && (target !== null)
// function deepClone1 (target, map = new WeakMap()) {
//   if (map.get(target)) {
//     return target
//   }
//   let constructor = target.constructor
//   if (/^(RegExp|Date)$/i.test(constructor.name)) {
//     return new constructor(target)
//   }
//   if (isObject1(target)) {
//     map.set(target, true)
//     if (typeof target === 'function') {
//       return target
//     }
//     let cloneTarget = Array.isArray(target) ? [] : {}
//     for (let key in target) {
//       if (target.hasOwnProperty(key)) {
//         cloneTarget[key] = deepClone1(target[key], map)
//       }
//     }
//     return cloneTarget
//   } else {
//     return target
//   }
// }

